<?php

namespace App\Jobs\DSE;

use App\Models\Account;
use App\Models\Game;
use App\Models\GameCell;
use App\Models\Profit;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Throwable;

class ReturnDseJob implements ShouldQueue
{
    use Dispatchable;
    use InteractsWithQueue;
    use Queueable;
    use SerializesModels;

    protected $game_id;
    protected $row;

    public function __construct($game_id, $row)
    {
        $this->game_id = $game_id;
        $this->row = $row;
    }

    public function handle()
    {
        try {
            logger('==每环结束返DSE结算==');
            $this->leader();
        } catch (\Throwable $throwable) {
            Log::info($throwable);
        }
    }

    /**
     * 1、当前环每个节点收益=当前环token * 50% / 当前环节点个数
     * 2、上面环有效节点收益=当前环token * 50% / 上面环有效节点个数
     * 3、本金返还
     */
    protected function leader()
    {
        if ($this->row <= 1) {
            return;
        }
        $curRow = Game::getRow($this->row);
        logger($curRow);
        logger('节点个数 ：'.$curRow['node'] . '，token数量：'. $curRow['token']);

        /*****************当前环收益 BEGIN*******************/
        $reward1 = bcdiv(bcmul($curRow['token'], 0.5), $curRow['node'], 6);
        GameCell::where('game_id', $this->game_id)->where('row', $this->row)->each(function ($cell) use ($reward1){
            if (!Profit::where('game_id', $this->game_id)->where('cell_id', $cell->id)->where('type', 1)->exists()) {
                $inAccount = Account::firstOrCreate([
                    'user_id' => $cell->user_id,
                    'coin_id' => 2,
                ]);
                // 环收益明细
                $profit = new Profit();
                $profit->user_id = $cell->user_id;
                $profit->game_id = $this->game_id;
                $profit->row = $this->row;
                $profit->cell_id = $cell->id;
                $profit->type = 1;
                $profit->profit = $reward1;
                $profit->time = now();
                logger("user_id:".$cell->user_id.'，当前环收益：'.$profit->profit);
                try {
                    DB::transaction(function () use ($profit, $inAccount) {
                        /** @var Account $inAccount */
                        $inAccount = Account::lockForUpdate()->find($inAccount->id);

                        $profit->save();

                        $inAccount->freezeIncrement($profit->profit);
                        $inAccount->type = '当前环收益';
                        $inAccount->action_id = $profit->id;
                        $inAccount->save();
                    });
                } catch (Throwable $exception) {
                    Log::error($exception);
                }
            }
        });
        /*****************当前环收益   END*******************/

        /*****************上面环收益 BEGIN*******************/
        $nodeNum = GameCell::where('game_id', $this->game_id)->where('row', '<', $this->row)->where('last_row', '>=', $this->row)->count();
        logger('上面环有效节点个数：'.$nodeNum);
        $reward2 = bcdiv(bcmul($curRow['token'], 0.5), $nodeNum, 6);
        GameCell::where('game_id', $this->game_id)->where('row', '<', $this->row)->where('last_row', '>=', $this->row)->each(function ($cell) use ($reward2) {
            if (!Profit::where('game_id', $this->game_id)->where('row', $this->row)->where('cell_id', $cell->id)->where('type', 2)->exists()) {
                $inAccount = Account::firstOrCreate([
                    'user_id' => $cell->user_id,
                    'coin_id' => 2,
                ]);
                // 环收益明细
                $profit = new Profit();
                $profit->user_id = $cell->user_id;
                $profit->game_id = $this->game_id;
                $profit->row = $this->row;
                $profit->cell_id = $cell->id;
                $profit->type = 2;
                $profit->profit = $reward2;
                $profit->time = now();
                logger("user_id:".$cell->user_id.'，上面环收益：'.$profit->profit);
                try {
                    DB::transaction(function () use ($profit, $inAccount) {
                        /** @var Account $inAccount */
                        $inAccount = Account::lockForUpdate()->find($inAccount->id);

                        $profit->save();

                        $inAccount->freezeIncrement($profit->profit);
                        $inAccount->type = '上面环收益';
                        $inAccount->action_id = $profit->id;
                        $inAccount->save();
                    });
                } catch (Throwable $exception) {
                    Log::error($exception);
                }
            }
        });
        /*****************上面环收益   END*******************/

        /*****************本金返还 BEGIN*******************/
        if ($this->row >= 100) {
            logger('第'.$this->row.'环结束，第'.($this->row-99).'环本金返还');
            GameCell::where('game_id', $this->game_id)->where('row', $this->row-99)->each(function ($cell) {
                if (!Profit::where('game_id', $this->game_id)->where('cell_id', $cell->id)->where('type', 3)->exists()) {
                    $inAccount = Account::firstOrCreate([
                        'user_id' => $cell->user_id,
                        'coin_id' => 2,
                    ]);
                    // 本金返还明细
                    $profit = new Profit();
                    $profit->user_id = $cell->user_id;
                    $profit->game_id = $this->game_id;
                    $profit->row = $this->row;
                    $profit->cell_id = $cell->id;
                    $profit->type = 3;
                    $profit->profit = 10;
                    $profit->time = now();
                    logger("user_id:".$cell->user_id.'，本金返还：'.$profit->profit);
                    try {
                        DB::transaction(function () use ($profit, $inAccount) {
                            /** @var Account $inAccount */
                            $inAccount = Account::lockForUpdate()->find($inAccount->id);

                            $profit->save();

                            $inAccount->freezeIncrement($profit->profit);
                            $inAccount->disabledDecrement(min($inAccount->disabled, 10));
                            $inAccount->type = '本金返还';
                            $inAccount->action_id = $profit->id;
                            $inAccount->save();
                        });
                    } catch (Throwable $exception) {
                        Log::error($exception);
                    }
                }
            });
        }
        /*****************本金返还   END*******************/
    }
}
